1 Read and Merge

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Read and Merge
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wd <- "E:/Cinetic idei noi/EXPERIMENTE OGL Frontiers (O.2 & O.0.3 & O.0.2)"
setwd(wd)
DataTrust <- rio::import(file.path(wd, "O.2 REZULTATE\\O.2 Date PrelucrareSPSS cu NEO si STAI", "O.2 Date pt Trust BUN cu NEO si STAIY.xlsx"))
DataDG <- rio::import(file.path(wd, "O.2 REZULTATE\\O.2 Date PrelucrareSPSS cu NEO si STAI", "O.2 Date pt DG BUN cu NEO si STAIY.xlsx"))
DataVAS <- rio::import(file.path(wd, "O.2 REZULTATE\\O.2 VAS,IOS", "O.2 Date PrelucrareSPSS.xlsx"))
DataBIO <- rio::import(file.path(wd, "O.2 BIO", "O.2 Ox si Cortizol.xlsx"))
  
Data_merge1 <- merge(DataVAS, DataTrust)  
Data_merge2 <- merge(Data_merge1, DataDG) 
Data_merge3 <- merge(Data_merge2, DataBIO)
Data <- Data_merge3
test_names <- unique(unlist(lapply(list(DataTrust, DataDG, DataVAS, DataBIO), names)))
merge_names <- names(Data)
if(identical(merge_names[order(merge_names)], test_names[order(test_names)])){    # the order matters in identical()
  cat("**Merge was succesful**")
  rm("Data_merge1", "Data_merge2", "Data_merge3", "DataBIO", "DataDG", "DataTrust", "DataVAS", "test_names", "merge_names")
}else cat("**Merge unsuccesful**") 

Merge was succesful

2 Derive new variables (not used here)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Derive new variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Data$D_VasS_Poz <- Data[, "VasS_postPoz"] - Data[, "VasS_prePoz"] 
Data$D_VasS_Neg <- Data[, "VasS_postNeg"] - Data[, "VasS_preNeg"]
Data$D_VasB_Poz <- Data[, "VasB_postPoz"] - Data[, "VasB_prePoz"] 
Data$D_VasB_Neg <- Data[, "VasB_postNeg"] - Data[, "VasB_preNeg"]
Data$D_IOS_Poz <- Data[, "IOS_postPoz"] - Data[, "IOS_prePoz"] 
Data$D_IOS_Neg <- Data[, "IOS_postNeg"] - Data[, "IOS_preNeg"]

Data$D_Sam1_Poz <- Data[, "Sam1_postPoz"] - Data[, "Sam1_prePoz"] 
Data$D_Sam1_Neg <- Data[, "Sam1_postNeg"] - Data[, "Sam1_preNeg"]
Data$D_Sam2_Poz <- Data[, "Sam2_postPoz"] - Data[, "Sam2_prePoz"] 
Data$D_Sam2_Neg <- Data[, "Sam2_postNeg"] - Data[, "Sam2_preNeg"]
Data$D_Sam3_Poz <- Data[, "Sam3_postPoz"] - Data[, "Sam3_prePoz"] 
Data$D_Sam3_Neg <- Data[, "Sam3_postNeg"] - Data[, "Sam3_preNeg"]

Data$D_DG_Poz <- Data[, "DG_postPozTot"] - Data[, "DG_prePozTot"] 
Data$D_DG_Neg <- Data[, "DG_postNegTot"] - Data[, "DG_preNegTot"]

Data$D_TrustMin_Poz <- Data[, "TrustMinPozPost"] - Data[, "TrustMinPozPre"] 
Data$D_TrustMin_Neg <- Data[, "TrustMinNegPost"] - Data[, "TrustMinNegPre"]
Data$D_TrustTot_Poz <- Data[, "TrustTotPozPost"] - Data[, "TrustTotPozPre"] 
Data$D_TrustTot_Neg <- Data[, "TrustTotNegPost"] - Data[, "TrustTotNegPre"]

Data$D_Cort_Poz <- Data[, "Cort_post_Poz"] - Data[, "Cort_pre_Poz"] 
Data$D_Cort_Neg <- Data[, "Cort_post_Neg"] - Data[, "Cort_pre_Neg"]
Data$D_Ox_Poz <- Data[, "Ox_post_Poz"] - Data[, "Ox_pre_Poz"] 
Data$D_Ox_Neg <- Data[, "Ox_post_Neg"] - Data[, "Ox_pre_Neg"]

2.1 Define Functions

find_med <- function(df, dfp = NULL, num_only = TRUE, verbose = TRUE) {
  count = 0
  mediation_model_list <<- list()
  
  if(num_only == TRUE){
  numeric_cols <- unlist(lapply(df, is.numeric))                                      # get only numeric columns
  df <- df[, numeric_cols]
  }
  
  # permutations for Mediation - Check: factorial(len_names)/factorial(len_names-3)
  names <- colnames(df)
  len_names = length(names)
  
  if(is.null(dfp)){
    dfp <- lapply(1:len_names, function(i){
      tmp <- lapply(1:len_names, function(j){
        tmp <- lapply(1:len_names, function(k){
          if(j != i & k != i & k != j) c(names[i], names[j], names[k])
        })
        do.call(rbind, tmp)
      })
      do.call(rbind, tmp)
    })
    dfp <- do.call(rbind.data.frame, dfp)
    names(dfp) <- paste("var", 1:3, sep = "_")
    dfp[, ] <- lapply(dfp[, ], as.character)    
  } else {
    dfp <- dfp
  }
  
  
  for (row in 1:nrow(dfp)) {                
    
    results <- medmod::med(data = df,                                                  
                          dep = dfp[row, 1], med = dfp[row, 2], pred = dfp[row, 3], 
                          ci = TRUE, label = TRUE, 
                          paths = TRUE, pm = TRUE, 
                          estPlot = FALSE)             
    
    pmed <- as.data.frame(results$med)[1, 8]           # p-value of Indirect Effect
    if(pmed < 0.05 && !is.na(pmed)) {
      count <- count + 1
      if(verbose == TRUE) {
        cat("Mediator Variable:", dfp[row, 2], "| Predictor:", dfp[row, 3], "| Dependent:", dfp[row, 1])
        print(results$med)
        print(results$paths)
      }
      mediation_model_list[["MedEs"]][[paste("model", count, sep = "_")]] <<- as.data.frame(results$med)   # return as list of dataframes
      mediation_model_list[["PathEs"]][[paste("model", count, sep = "_")]] <<- as.data.frame(results$paths)
      mediation_model_list[["Syntax"]][[paste("model", count, sep = "_")]] <<- results$modelSyntax
    }
  }
  cat("\n","Report: ", count, "significant mediations out of", row, "total tries.")
}
find_mod <- function(df, dfp = NULL, num_only = TRUE, verbose = TRUE) {
  count = 0
  moderation_model_list <<- list()
  if(num_only == TRUE){
  numeric_cols <- unlist(lapply(df, is.numeric))                                      # get only numeric columns
  df <- df[, numeric_cols]
  }
  
  # restricted permutations for Moderation - Check: choose(len_names, 3)*3
  names <- colnames(df)
  len_names = length(names)
  
  if(is.null(dfp)){
    dfp <- lapply(1:len_names, function(i){
      tmp <- lapply(1:(len_names-1), function(j){
        tmp <- lapply((j+1):len_names, function(k){
          if(j != i & k != i) c(names[i], names[j], names[k])
        })
        do.call(rbind, tmp)
      })
      do.call(rbind, tmp)
    })
    dfp <- do.call(rbind.data.frame, dfp)
    names(dfp) <- paste("var", 1:3, sep = "_")
    dfp[, ] <- lapply(dfp[, ], as.character)    
  } else {
    dfp <- dfp
  }
  
  for (row in 1:nrow(dfp)) {                
    
    results <- medmod::mod(data = df,                                                   # mod does centering automatically
                          dep = dfp[row, 1], mod = dfp[row, 2], pred = dfp[row, 3], 
                          estMethod = "standard", test = TRUE, 
                          simpleSlopeEst = FALSE, simpleSlopePlot = FALSE)             # when testing use estMethod = 'bootstrap', bootstrap = 500 
    
    pmod <- as.data.frame(results$mod)[3,5]
    if(pmod < 0.05 && !is.na(pmod)) {
      count <- count + 1
        if(verbose == TRUE) {
        cat("Dependent Variable:", dfp[row, 1])
        print(results$mod) 
        }
      moderation_model_list[["Model"]][[paste("model", count, sep = "_")]] <<- as.data.frame(results$mod)   # return as list of dataframes
      moderation_model_list[["Syntax"]][[paste("model", count, sep = "_")]] <<- results$modelSyntax
      
    }
  }
  cat("\n","Report: ", count, "significant moderations out of", row, "total tries.")
}
#######################################################################################################################################
## LCS ANCOVA mediation function (adapted for lavaan from doi: 10.1080/10705511.2016.1274657)
#######################################################################################################################################
library(lavaan)
library(semPlot)
lcs_ancova_med <- function(df, x, y1, y2, m1, m2){
  
  arguments <- as.list(match.call())
  x = eval(arguments$x, df)
  y1 = eval(arguments$y1, df)
  y2 = eval(arguments$y2, df)
  m1 = eval(arguments$m1, df)
  m2 = eval(arguments$m2, df)  
  
  df_mod <- data.frame(x, y1, y2, m1, m2)     # use this df creating part like this: lcs_ancova_med(mtcars, mpg, cyl, disp, hp, drat)
  mod_syntax <- 
  '
  # Defining change in M as a function of M1 and M2
  deltam =~ 1*m2
  deltam ~~ deltam
  deltam ~ 1
  m2 ~ 1*m1
  m2 ~~ 0*m1
  m2 ~~ 0*m2
  m2 ~ 0*1
  m1 ~ 1
  # Defining the change in Y as a function of Y1 and Y2
  deltay =~ 1*y2
  deltay ~~ deltay
  deltay ~ 1
  y2 ~ 1*y1
  y2 ~~ 0*y1
  y2 ~~ 0*y2
  y2 ~ 0*1
  y1 ~ 1
  # Estimating the Pretest correlation between M1 and Y1 and Variance of X
  m1 ~~ y1
  # Estimated covariance between M1 and X and Y1 and X because these covariances may not be equal to zero especially 
  # if X is not a randomized experiment without these the model has 2 degrees of freedom (covariances are only constrained to zero) 
  # but ANCOVA model should start out as saturated and have 0 degrees of freedom 
  m1 ~~ x # these covariances may not be equal to zero especially if X is not a randomized experiment
  x ~~ y1 # these covariances may not be equal to zero especially if X is not a randomized experiment
  # Regression of change in M on X and pretest measures
  deltam ~ am2x*x + sm1*m1 + y1
  # Regression of change in Y on X, change in M, and pretest measures
  deltay ~ x + by2m2*deltam + b*m1 + sy1*y1
  
  # Making constraints to match estimates to ANCOVA
  # Estimate of effect of M1 on M2 in ANCOVA
  sm := sm1+1 
  # Estimate of effect of Y1 on Y2 in ANCOVA
  sy := sy1+1 
  # Estimate of effect of M1 on Y2 in ANCOVA
  by2m1 := b-by2m2 
  # Estimate of mediated effect
  med := am2x*by2m2 
  '  
  
  mod <- lavaan::sem(model = mod_syntax, data = df_mod, test = "bootstrap")  
}
#######################################################################################################################################
# Use - dont run
#######################################################################################################################################
# mod <- lcs_ancova_med(df = df2, x = Cond, y1 = Out1, y2 = Out2, m1 = Med1, m2 = Med2)
# 
# summary(mod, standardized = TRUE)
# semPlot::semPaths(mod, layout = "spring",  nCharNodes = 0, nCharEdges = 0, what = "path", whatLabels = "path", edge.label.cex = 0.8) 

3 Downloadable Table

Data %>% 
  select(-"Nume Prenume") %>%
    DT::datatable(                                  # excel downloadable  DT table
      extensions = 'Buttons',
      options = list(pageLength = 10,
                     scrollX='500px', 
                     dom = 'Bfrtip', 
                     buttons = c('excel', "csv")))

4 Analyses

4.1 Melt Data

Data_med <- Data %>%
  select(-c(1:4,6,7), 
         -c("DG_prePoz1", "DG_prePoz2", "DG_prePoz3", "DG_postPoz1", "DG_postPoz2", "DG_postPoz3",  
           "DG_preNeg1", "DG_preNeg2", "DG_preNeg3" , "DG_postNeg1", "DG_postNeg2", "DG_postNeg3"))
## Data not melted to long
# Data_med %>%
#   find_med()       # not run here to keep report clean
## Data melted to long (Cond = Poz/Neg)
# Data_med_melt <- 
#   Data_med %>%
#     dplyr::rename_all(list(~stringr::str_replace_all(., "Pre|_pre|_Pre", "_pre"))) %>%         # consistent Condition and Time
#     dplyr::rename_all(list(~stringr::str_replace_all(., "Post|_post|_Post", "_post"))) %>%
#     dplyr::rename_all(list(~stringr::str_replace_all(., "Poz|poz|_Poz|_poz", "_poz"))) %>%
#     dplyr::rename_all(list(~stringr::str_replace_all(., "Neg|neg|_Neg|_neg", "_neg"))) %>%
#     dplyr::rename_all(list(~stringr::str_replace_all(., "_neg_pre", "_pre_neg"))) %>%          # consistent ordering in names
#     dplyr::rename_all(list(~stringr::str_replace_all(., "_neg_post", "_post_neg"))) %>%
#     dplyr::rename_all(list(~stringr::str_replace_all(., "_poz_pre", "_pre_poz"))) %>%
#     dplyr::rename_all(list(~stringr::str_replace_all(., "_poz_post", "_post_poz"))) %>%
#     dplyr::rename_all(list(~stringr::str_replace_all(., "Tot", ""))) %>%                       # detele Tot "DG_pre_negTot", "TrustTot_post_poz"
#     gather(Var, Val, -c(1:38)) %>%
#     separate(Var, into = c("Var", "Time", "Condition")) %>%
#     mutate(Time = factor(Time, levels = c("pre", "post"))) %>%
#     mutate(Condition = factor(Condition, levels = c("poz", "neg"))) %>%
#     spread(Var, Val) 
Data_med_melt <- 
  Data_med %>%
    dplyr::rename_all(list(~stringr::str_replace_all(., "Pre|_pre|_Pre", "_pre"))) %>%         # consistent Condition and Time
    dplyr::rename_all(list(~stringr::str_replace_all(., "Post|_post|_Post", "_post"))) %>%
    dplyr::rename_all(list(~stringr::str_replace_all(., "Poz|poz|_Poz|_poz", "_poz"))) %>%
    dplyr::rename_all(list(~stringr::str_replace_all(., "Neg|neg|_Neg|_neg", "_neg"))) %>%
    dplyr::rename_all(list(~stringr::str_replace_all(., "_neg_pre", "_pre_neg"))) %>%          # consistent ordering in names
    dplyr::rename_all(list(~stringr::str_replace_all(., "_neg_post", "_post_neg"))) %>%
    dplyr::rename_all(list(~stringr::str_replace_all(., "_poz_pre", "_pre_poz"))) %>%
    dplyr::rename_all(list(~stringr::str_replace_all(., "_poz_post", "_post_poz"))) %>%
    dplyr::rename_all(list(~stringr::str_replace_all(., "Tot", ""))) %>%                       # detele Tot "DG_pre_negTot", "TrustTot_post_poz"
    gather(Var, Val, -c(1:38)) %>%
    tidyr::separate(Var, into = c("Var", "Time", "Condition")) %>%
    tidyr::unite("Var", c("Var", "Time")) %>%
    mutate(Condition = factor(Condition, levels = c("poz", "neg"))) %>%
    mutate(Condition = dplyr::recode(Condition, "poz" = 1, "neg" = 2)) %>% 
    spread(Var, Val) 

4.2 Search Mediations and Moderations

dfp <- data.frame(
  var1 = colnames(Data_med_melt)[grep("_post", colnames(Data_med_melt))],
  var2 = rep("Condition", 13),
  var3 = colnames(Data_med_melt)[grep("_pre", colnames(Data_med_melt))],
  stringsAsFactors = FALSE
)
find_med(df = Data_med_melt, dfp = dfp, num_only = FALSE)                 # nothing
find_mod(df = Data_med_melt, dfp = dfp, num_only = FALSE)                 # DG_pre:Condition
# medmod::med(data = Data_med_melt,                                                  
#            dep = "Ox_post", med = "Condition", pred = "Ox_pre", 
#            ci = TRUE, label = TRUE, 
#            paths = TRUE, pm = TRUE, 
#            estPlot = FALSE)
# 
# medmod::mod(data = Data_med_melt,                                                   # mod does centering automatically
#             dep = "Ox_post", mod = "Condition", pred = "Ox_pre",  
#             estMethod = "standard", test = TRUE, 
#             simpleSlopeEst = FALSE, simpleSlopePlot = FALSE)
# mediation_model_list$Model   # no models to show
moderation_model_list$Model %>% 
  knitr::kable(digits = 2)
term est se z p
DG_pre 0.64 0.06 10.50 0.00
Condition 40.39 29.01 1.39 0.16
DG_pre:Condition -0.36 0.12 -2.92 0.00

4.3 LCS ANCOVA longitudinal mediation

Data_med_melt_transform <- Data_med_melt    # some observed variances are (at least) a factor 1000 times larger than others
Data_med_melt_transform$DG_pre <- Data_med_melt_transform$DG_pre / 100  
Data_med_melt_transform$DG_post <- Data_med_melt_transform$DG_post / 100
mod <- lcs_ancova_med(df = Data_med_melt_transform, x = Condition, y1 = DG_pre, y2 = DG_post, m1 = Ox_pre, m2 = Ox_post)
summary(mod, standardized = TRUE)    # nope
lavaan 0.6-4 ended normally after 47 iterations

  Optimization method                           NLMINB
  Number of free parameters                         20

                                                  Used       Total
  Number of observations                            59          60

  Estimator                                         ML
  Model Fit Test Statistic                       0.000
  Degrees of freedom                                 0
  P-value (Bollen-Stine Bootstrap)               0.644

Parameter Estimates:

  Information                                 Expected
  Information saturated (h1) model          Structured
  Standard Errors                             Standard

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  deltam =~                                                             
    m2                1.000                               0.629    0.897
  deltay =~                                                             
    y2                1.000                               1.509    0.775

Regressions:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  m2 ~                                                                  
    m1                1.000                               1.000    0.770
  y2 ~                                                                  
    y1                1.000                               1.000    1.227
  deltam ~                                                              
    x       (am2x)    0.023    0.158    0.144    0.885    0.036    0.018
    m1       (sm1)   -0.320    0.146   -2.188    0.029   -0.508   -0.274
    y1               -0.036    0.033   -1.104    0.269   -0.057   -0.137
  deltay ~                                                              
    x                 0.397    0.310    1.280    0.200    0.263    0.131
    deltam  (by22)    0.485    0.256    1.894    0.058    0.202    0.202
    m1         (b)    0.090    0.299    0.303    0.762    0.060    0.032
    y1       (sy1)   -0.352    0.065   -5.427    0.000   -0.233   -0.558

Covariances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
 .m2 ~~                                                                 
    m1                0.000                               0.000      NaN
 .y2 ~~                                                                 
    y1                0.000                               0.000      NaN
  m1 ~~                                                                 
    y1                0.100    0.169    0.596    0.551    0.100    0.078
    x                -0.042    0.036   -1.175    0.240   -0.042   -0.155
  y1 ~~                                                                 
    x                 0.053    0.156    0.341    0.733    0.053    0.044

Intercepts:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .deltam            0.790    0.359    2.204    0.028    1.256    1.256
   .m2                0.000                               0.000    0.000
    m1                0.776    0.070   11.027    0.000    0.776    1.436
   .deltay            2.190    0.734    2.983    0.003    1.451    1.451
   .y2                0.000                               0.000    0.000
    y1                7.229    0.311   23.227    0.000    7.229    3.024
    x                 1.508    0.065   23.177    0.000    1.508    3.017

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .deltam            0.356    0.066    5.431    0.000    0.898    0.898
   .m2                0.000                               0.000    0.000
   .deltay            1.379    0.254    5.431    0.000    0.605    0.605
   .y2                0.000                               0.000    0.000
    m1                0.292    0.054    5.431    0.000    0.292    1.000
    y1                5.715    1.052    5.431    0.000    5.715    1.000
    x                 0.250    0.046    5.431    0.000    0.250    1.000

Defined Parameters:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    sm                0.680    0.146    4.661    0.000    0.492    0.726
    sy                0.648    0.065    9.976    0.000    0.767    0.442
    by2m1            -0.395    0.336   -1.175    0.240   -0.142   -0.170
    med               0.011    0.077    0.144    0.886    0.007    0.004
semPlot::semPaths(mod, layout = "spring",  nCharNodes = 0, nCharEdges = 0, what = "path", whatLabels = "path", edge.label.cex = 0.8) 

# mod <- lcs_ancova_med(df = Data_med_melt, x = Condition, y1 = VasS_pre, y2 = VasS_post, m1 = Ox_pre, m2 = Ox_post)
# summary(mod, standardized = TRUE)    # nope
# 
# mod <- lcs_ancova_med(df = Data_med_melt, x = Condition, y1 = VasB_pre, y2 = VasB_post, m1 = Ox_pre, m2 = Ox_post)
# summary(mod, standardized = TRUE)    # nope
# 
# mod <- lcs_ancova_med(df = Data_med_melt, x = Condition, y1 = IOS_pre, y2 = IOS_post, m1 = Ox_pre, m2 = Ox_post)
# summary(mod, standardized = TRUE)    # nope
# 
# mod <- lcs_ancova_med(df = Data_med_melt, x = Condition, y1 = Trust_pre, y2 = Trust_post, m1 = Ox_pre, m2 = Ox_post)
# summary(mod, standardized = TRUE)    # nope
# 
# 
# 
# mod <- lcs_ancova_med(df = Data_med_melt, x = Condition, y1 = Ox_pre, y2 = Ox_post, m1 = IOS_pre, m2 = IOS_post)
# summary(mod, standardized = TRUE)    # nope
# 
# mod <- lcs_ancova_med(df = Data_med_melt, x = Condition, y1 = Ox_pre, y2 = Ox_post, m1 = VasS_pre, m2 = VasS_post)
# summary(mod, standardized = TRUE)    # nope
# 
# mod <- lcs_ancova_med(df = Data_med_melt, x = Condition, y1 = Ox_pre, y2 = Ox_post, m1 = VasB_pre, m2 = VasB_post)
# summary(mod, standardized = TRUE)    # nope
# 
# 
# 
# mod <- lcs_ancova_med(df = Data_med_melt, x = Condition, y1 = Cort_pre, y2 = Cort_post, m1 = IOS_pre, m2 = IOS_post)
# summary(mod, standardized = TRUE)    # nope
# 
# mod <- lcs_ancova_med(df = Data_med_melt, x = Condition, y1 = Cort_pre, y2 = Cort_post, m1 = VasS_pre, m2 = VasS_post)
# summary(mod, standardized = TRUE)    # nope
# 
# mod <- lcs_ancova_med(df = Data_med_melt, x = Condition, y1 = Cort_pre, y2 = Cort_post, m1 = VasB_pre, m2 = VasB_post)
# summary(mod, standardized = TRUE)    # nope



5 Session Info

R version 3.5.2 (2018-12-20)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=Romanian_Romania.1250  LC_CTYPE=Romanian_Romania.1250    LC_MONETARY=Romanian_Romania.1250 LC_NUMERIC=C                     
[5] LC_TIME=Romanian_Romania.1250    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] semPlot_1.1        lavaan_0.6-4       rio_0.5.16         plyr_1.8.4         summarytools_0.9.3 DT_0.5             ggpubr_0.2        
 [8] magrittr_1.5       broom_0.5.1        papaja_0.1.0.9842  psych_1.8.10       forcats_0.3.0      stringr_1.3.1      dplyr_0.7.8       
[15] purrr_0.2.5        readr_1.3.0        tidyr_0.8.2        tibble_1.4.2       ggplot2_3.2.0      tidyverse_1.2.1    pacman_0.5.1      

loaded via a namespace (and not attached):
  [1] readxl_1.1.0         backports_1.1.3      Hmisc_4.1-1          BDgraph_2.53         igraph_1.2.4.1       lazyeval_0.2.1      
  [7] splines_3.5.2        crosstalk_1.0.0      pryr_0.1.4           digest_0.6.18        htmltools_0.3.6      matrixcalc_1.0-3    
 [13] magick_2.0           checkmate_1.8.5      lisrelToR_0.1.4      cluster_2.0.7-1      openxlsx_4.1.0       sna_2.4             
 [19] modelr_0.1.2         matrixStats_0.54.0   jpeg_0.1-8           sem_3.1-9            colorspace_1.3-2     rvest_0.3.2         
 [25] haven_2.1.1          xfun_0.8             tcltk_3.5.2          crayon_1.3.4         RCurl_1.95-4.11      jsonlite_1.6        
 [31] lme4_1.1-19          bindr_0.1.1          survival_2.43-3      glue_1.3.1           gtable_0.2.0         mi_1.0              
 [37] medmod_1.0.0         ggm_2.3              abind_1.4-5          rapportools_1.0      scales_1.0.0         Rcpp_1.0.2          
 [43] xtable_1.8-3         htmlTable_1.12       foreign_0.8-71       Formula_1.2-3        stats4_3.5.2         htmlwidgets_1.3     
 [49] httr_1.4.0           RColorBrewer_1.1-2   acepack_1.4.1        pkgconfig_2.0.2      XML_3.98-1.16        nnet_7.3-12         
 [55] kutils_1.69          later_0.7.5          tidyselect_0.2.5     rlang_0.3.0.1        reshape2_1.4.3       munsell_0.5.0       
 [61] cellranger_1.1.0     tools_3.5.2          jmvcore_0.9.5.2      cli_1.0.1            generics_0.0.2       statnet.common_4.1.4
 [67] evaluate_0.14        fdrtool_1.2.15       arm_1.10-1           yaml_2.2.0           knitr_1.24           zip_1.0.0           
 [73] pander_0.6.3         bindrcpp_0.2.2       glasso_1.10          pbapply_1.3-4        nlme_3.1-137         mime_0.6            
 [79] whisker_0.3-2        xml2_1.2.0           compiler_3.5.2       rstudioapi_0.8       curl_4.0             png_0.1-7           
 [85] huge_1.2.7           pbivnorm_0.6.0       stringi_1.2.4        highr_0.7            qgraph_1.5           rockchalk_1.8.129   
 [91] lattice_0.20-38      Matrix_1.2-15        nloptr_1.2.1         pillar_1.3.1         OpenMx_2.11.5        data.table_1.12.2   
 [97] bitops_1.0-6         corpcor_1.6.9        httpuv_1.4.5         R6_2.4.0             latticeExtra_0.6-28  promises_1.0.1      
[103] network_1.13.0.1     gridExtra_2.3        codetools_0.2-15     boot_1.3-20          MASS_7.3-51.1        gtools_3.8.1        
[109] assertthat_0.2.1     rjson_0.2.20         withr_2.1.2          mnormt_1.5-5         parallel_3.5.2       hms_0.4.2           
[115] grid_3.5.2           rpart_4.1-13         coda_0.19-2          minqa_1.2.4          rmarkdown_1.14       carData_3.0-2       
[121] d3Network_0.5.2.1    semTools_0.5-1       shiny_1.2.0          lubridate_1.7.4      base64enc_0.1-3      ellipse_0.4.1       
 

A work by Claudiu Papasteri

claudiu.papasteri@gmail.com

 

LS0tDQp0aXRsZTogIjxicj4gTy4yIFJlcG9ydC1tZWRtb2QiIA0Kc3VidGl0bGU6ICJNZWRpYXRpb24gYW5kIE1vZGVyYXRpb24iDQphdXRob3I6ICI8YnI+IENsYXVkaXUgUGFwYXN0ZXJpIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJW0gJVknKWAiDQpvdXRwdXQ6IA0KICAgIGh0bWxfbm90ZWJvb2s6DQogICAgICAgICAgIyBzZWxmX2NvbnRhaW5lZDogbm8NCiAgICAgICAgICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgICAgICAgICAgdG9jOiB0cnVlDQogICAgICAgICAgICB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgICAgICAgICAgdGhlbWU6IHNwYWNlbGFiDQogICAgICAgICAgICBoaWdobGlnaHQ6IHRhbmdvDQogICAgICAgICAgICBmb250LWZhbWlseTogQXJpYWwNCiAgICAgICAgICAgIGZpZ193aWR0aDogMTANCiAgICAgICAgICAgIGZpZ19oZWlnaHQ6IDkNCiAgICAgIyBwZGZfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgIyB0b2M6IHRydWUNCiAgICAgICAgICAgICMgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICAjIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgICAgICAgICAgIyBmb250c2l6ZTogMTFwdA0KICAgICAgICAgICAgIyBnZW9tZXRyeTogbWFyZ2luPTFpbg0KICAgICAgICAgICAgIyBmaWdfd2lkdGg6IDcNCiAgICAgICAgICAgICMgZmlnX2hlaWdodDogNg0KICAgICAgICAgICAgIyBmaWdfY2FwdGlvbjogdHJ1ZQ0KICAgICMgZ2l0aHViX2RvY3VtZW50OiANCiAgICAgICAgICAgICMgdG9jOiB0cnVlDQogICAgICAgICAgICAjIHRvY19kZXB0aDogMg0KICAgICAgICAgICAgIyBodG1sX3ByZXZpZXc6IGZhbHNlDQogICAgICAgICAgICAjIGZpZ193aWR0aDogNQ0KICAgICAgICAgICAgIyBmaWdfaGVpZ2h0OiA1DQogICAgICAgICAgICAjIGRldjoganBlZw0KLS0tDQoNCg0KPCEtLSBTZXR1cCAtLT4NCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMga2ludHIgb3B0aW9ucw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBjb21tZW50ID0gIiMiLA0KICBjb2xsYXBzZSA9IFRSVUUsDQogIGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gVFJVRSwgbWVzc2FnZSA9IFRSVUUsIGNhY2hlID0gVFJVRSAgICAgICAjIGVjaG8gPSBGYWxzZSBmb3IgZ2l0aHViX2RvY3VtZW50LCBidXQgd2lsbCBiZSBmb2xkZWQgaW4gaHRtbF9ub3RlYm9vaw0KKQ0KDQojIEdlbmVyYWwgUiBvcHRpb25zIGFuZCBpbmZvDQpzZXQuc2VlZCgxMTEpICAgICAgICAgICAgICAgIyBpbiBjYXNlIHdlIHVzZSByYW5kb21pemVkIHByb2NlZHVyZXMgICAgICAgDQpvcHRpb25zKHNjaXBlbiA9IDk5OSkgICAgICAgIyBwb3NpdGl2ZSB2YWx1ZXMgYmlhcyB0b3dhcmRzIGZpeGVkIGFuZCBuZWdhdGl2ZSB0b3dhcmRzIHNjaWVudGlmaWMgbm90YXRpb24NCg0KIyBMb2FkIHBhY2thZ2VzDQppZiAoIXJlcXVpcmUoInBhY21hbiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KcGFja2FnZXMgPC0gYygNCiAgInRpZHl2ZXJzZSIsICAgICAgIyBiZXN0IHRoaW5nIHRoYXQgaGFwcGVuZCB0byBtZQ0KICAicHN5Y2giLCAgICAgICAgICAjIGdlbmVyYWwgcHVycG9zZSB0b29sYm94IGZvciBwZXJzb25hbGl0eSwgcHN5Y2hvbWV0cmljIHRoZW9yeSBhbmQgZXhwZXJpbWVudGFsIHBzeWNob2xvZ3kNCiAgInBhcGFqYSIsICAgICAgICAgIyBmb3IgQVBBIHN0eWxlDQogICJicm9vbSIsICAgICAgICAgICMgZm9yIHRpZHkgbW9kZWxsaW5nDQogICJnZ3Bsb3QyIiwgICAgICAgICMgYmVzdCBwbG90cw0KICAiZ2dwdWJyIiwgICAgICAgICAjIGdncGxvdDIgdG8gcHVibGljYXRpb24gcXVhbGl0eQ0KICAiRFQiLCAgICAgICAgICAgICAjIG5pY2Ugc2VhcmNoYWJsZSBhbmQgZG93bmxvYWRhYmxlIHRhYmxlcw0KICAic3VtbWFyeXRvb2xzIiwNCiAgInBseXIiLCANCiAgInJpbyINCiAgIyAsIC4uLg0KKQ0KaWYgKCFyZXF1aXJlKCJwYWNtYW4iKSkgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCnBhY21hbjo6cF9sb2FkKGNoYXIgPSBwYWNrYWdlcykNCg0KIyBUaGVtZXMgZm9yIGdncGxvdDIgcGxvdGluZyAoaGVyZSB1c2VkIEFQQSBzdHlsZSkNCnRoZW1lX3NldCh0aGVtZV9hcGEoKSkNCmBgYA0KDQoNCg0KPCEtLSBSZXBvcnQgLS0+DQoNCg0KIyBSZWFkIGFuZCBNZXJnZQ0KDQoNCmBgYHtyIHJlYWRfbWVyZ2UsIHJlc3VsdHM9J2FzaXMnLCB3YXJuaW5nPUZBTFNFfQ0KI35+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KIyBSZWFkIGFuZCBNZXJnZQ0KI35+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0Kd2QgPC0gIkU6L0NpbmV0aWMgaWRlaSBub2kvRVhQRVJJTUVOVEUgT0dMIEZyb250aWVycyAoTy4yICYgTy4wLjMgJiBPLjAuMikiDQpzZXR3ZCh3ZCkNCg0KRGF0YVRydXN0IDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aCh3ZCwgIk8uMiBSRVpVTFRBVEVcXE8uMiBEYXRlIFByZWx1Y3JhcmVTUFNTIGN1IE5FTyBzaSBTVEFJIiwgIk8uMiBEYXRlIHB0IFRydXN0IEJVTiBjdSBORU8gc2kgU1RBSVkueGxzeCIpKQ0KRGF0YURHIDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aCh3ZCwgIk8uMiBSRVpVTFRBVEVcXE8uMiBEYXRlIFByZWx1Y3JhcmVTUFNTIGN1IE5FTyBzaSBTVEFJIiwgIk8uMiBEYXRlIHB0IERHIEJVTiBjdSBORU8gc2kgU1RBSVkueGxzeCIpKQ0KRGF0YVZBUyA8LSByaW86OmltcG9ydChmaWxlLnBhdGgod2QsICJPLjIgUkVaVUxUQVRFXFxPLjIgVkFTLElPUyIsICJPLjIgRGF0ZSBQcmVsdWNyYXJlU1BTUy54bHN4IikpDQpEYXRhQklPIDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aCh3ZCwgIk8uMiBCSU8iLCAiTy4yIE94IHNpIENvcnRpem9sLnhsc3giKSkNCiAgDQpEYXRhX21lcmdlMSA8LSBtZXJnZShEYXRhVkFTLCBEYXRhVHJ1c3QpICANCkRhdGFfbWVyZ2UyIDwtIG1lcmdlKERhdGFfbWVyZ2UxLCBEYXRhREcpIA0KRGF0YV9tZXJnZTMgPC0gbWVyZ2UoRGF0YV9tZXJnZTIsIERhdGFCSU8pDQoNCkRhdGEgPC0gRGF0YV9tZXJnZTMNCg0KdGVzdF9uYW1lcyA8LSB1bmlxdWUodW5saXN0KGxhcHBseShsaXN0KERhdGFUcnVzdCwgRGF0YURHLCBEYXRhVkFTLCBEYXRhQklPKSwgbmFtZXMpKSkNCm1lcmdlX25hbWVzIDwtIG5hbWVzKERhdGEpDQoNCmlmKGlkZW50aWNhbChtZXJnZV9uYW1lc1tvcmRlcihtZXJnZV9uYW1lcyldLCB0ZXN0X25hbWVzW29yZGVyKHRlc3RfbmFtZXMpXSkpeyAgICAjIHRoZSBvcmRlciBtYXR0ZXJzIGluIGlkZW50aWNhbCgpDQogIGNhdCgiKipNZXJnZSB3YXMgc3VjY2VzZnVsKioiKQ0KICBybSgiRGF0YV9tZXJnZTEiLCAiRGF0YV9tZXJnZTIiLCAiRGF0YV9tZXJnZTMiLCAiRGF0YUJJTyIsICJEYXRhREciLCAiRGF0YVRydXN0IiwgIkRhdGFWQVMiLCAidGVzdF9uYW1lcyIsICJtZXJnZV9uYW1lcyIpDQp9ZWxzZSBjYXQoIioqTWVyZ2UgdW5zdWNjZXNmdWwqKiIpIA0KYGBgDQoNCg0KIyBEZXJpdmUgbmV3IHZhcmlhYmxlcyAobm90IHVzZWQgaGVyZSkNCg0KYGBge3IgZGVyaXZlX3ZhciwgaGlkZT1UUlVFLCBldmFsPUZBTFNFfQ0KI35+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KIyBEZXJpdmUgbmV3IHZhcmlhYmxlcw0KI35+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KRGF0YSREX1Zhc1NfUG96IDwtIERhdGFbLCAiVmFzU19wb3N0UG96Il0gLSBEYXRhWywgIlZhc1NfcHJlUG96Il0gDQpEYXRhJERfVmFzU19OZWcgPC0gRGF0YVssICJWYXNTX3Bvc3ROZWciXSAtIERhdGFbLCAiVmFzU19wcmVOZWciXQ0KRGF0YSREX1Zhc0JfUG96IDwtIERhdGFbLCAiVmFzQl9wb3N0UG96Il0gLSBEYXRhWywgIlZhc0JfcHJlUG96Il0gDQpEYXRhJERfVmFzQl9OZWcgPC0gRGF0YVssICJWYXNCX3Bvc3ROZWciXSAtIERhdGFbLCAiVmFzQl9wcmVOZWciXQ0KRGF0YSREX0lPU19Qb3ogPC0gRGF0YVssICJJT1NfcG9zdFBveiJdIC0gRGF0YVssICJJT1NfcHJlUG96Il0gDQpEYXRhJERfSU9TX05lZyA8LSBEYXRhWywgIklPU19wb3N0TmVnIl0gLSBEYXRhWywgIklPU19wcmVOZWciXQ0KDQpEYXRhJERfU2FtMV9Qb3ogPC0gRGF0YVssICJTYW0xX3Bvc3RQb3oiXSAtIERhdGFbLCAiU2FtMV9wcmVQb3oiXSANCkRhdGEkRF9TYW0xX05lZyA8LSBEYXRhWywgIlNhbTFfcG9zdE5lZyJdIC0gRGF0YVssICJTYW0xX3ByZU5lZyJdDQpEYXRhJERfU2FtMl9Qb3ogPC0gRGF0YVssICJTYW0yX3Bvc3RQb3oiXSAtIERhdGFbLCAiU2FtMl9wcmVQb3oiXSANCkRhdGEkRF9TYW0yX05lZyA8LSBEYXRhWywgIlNhbTJfcG9zdE5lZyJdIC0gRGF0YVssICJTYW0yX3ByZU5lZyJdDQpEYXRhJERfU2FtM19Qb3ogPC0gRGF0YVssICJTYW0zX3Bvc3RQb3oiXSAtIERhdGFbLCAiU2FtM19wcmVQb3oiXSANCkRhdGEkRF9TYW0zX05lZyA8LSBEYXRhWywgIlNhbTNfcG9zdE5lZyJdIC0gRGF0YVssICJTYW0zX3ByZU5lZyJdDQoNCkRhdGEkRF9ER19Qb3ogPC0gRGF0YVssICJER19wb3N0UG96VG90Il0gLSBEYXRhWywgIkRHX3ByZVBvelRvdCJdIA0KRGF0YSREX0RHX05lZyA8LSBEYXRhWywgIkRHX3Bvc3ROZWdUb3QiXSAtIERhdGFbLCAiREdfcHJlTmVnVG90Il0NCg0KRGF0YSREX1RydXN0TWluX1BveiA8LSBEYXRhWywgIlRydXN0TWluUG96UG9zdCJdIC0gRGF0YVssICJUcnVzdE1pblBvelByZSJdIA0KRGF0YSREX1RydXN0TWluX05lZyA8LSBEYXRhWywgIlRydXN0TWluTmVnUG9zdCJdIC0gRGF0YVssICJUcnVzdE1pbk5lZ1ByZSJdDQpEYXRhJERfVHJ1c3RUb3RfUG96IDwtIERhdGFbLCAiVHJ1c3RUb3RQb3pQb3N0Il0gLSBEYXRhWywgIlRydXN0VG90UG96UHJlIl0gDQpEYXRhJERfVHJ1c3RUb3RfTmVnIDwtIERhdGFbLCAiVHJ1c3RUb3ROZWdQb3N0Il0gLSBEYXRhWywgIlRydXN0VG90TmVnUHJlIl0NCg0KRGF0YSREX0NvcnRfUG96IDwtIERhdGFbLCAiQ29ydF9wb3N0X1BveiJdIC0gRGF0YVssICJDb3J0X3ByZV9Qb3oiXSANCkRhdGEkRF9Db3J0X05lZyA8LSBEYXRhWywgIkNvcnRfcG9zdF9OZWciXSAtIERhdGFbLCAiQ29ydF9wcmVfTmVnIl0NCkRhdGEkRF9PeF9Qb3ogPC0gRGF0YVssICJPeF9wb3N0X1BveiJdIC0gRGF0YVssICJPeF9wcmVfUG96Il0gDQpEYXRhJERfT3hfTmVnIDwtIERhdGFbLCAiT3hfcG9zdF9OZWciXSAtIERhdGFbLCAiT3hfcHJlX05lZyJdDQpgYGANCg0KDQojIyBEZWZpbmUgRnVuY3Rpb25zDQoNCmBgYHtyIGRlZl9mdW5fbWVkbW9kfQ0KZmluZF9tZWQgPC0gZnVuY3Rpb24oZGYsIGRmcCA9IE5VTEwsIG51bV9vbmx5ID0gVFJVRSwgdmVyYm9zZSA9IFRSVUUpIHsNCiAgY291bnQgPSAwDQogIG1lZGlhdGlvbl9tb2RlbF9saXN0IDw8LSBsaXN0KCkNCiAgDQogIGlmKG51bV9vbmx5ID09IFRSVUUpew0KICBudW1lcmljX2NvbHMgPC0gdW5saXN0KGxhcHBseShkZiwgaXMubnVtZXJpYykpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGdldCBvbmx5IG51bWVyaWMgY29sdW1ucw0KICBkZiA8LSBkZlssIG51bWVyaWNfY29sc10NCiAgfQ0KICANCiAgIyBwZXJtdXRhdGlvbnMgZm9yIE1lZGlhdGlvbiAtIENoZWNrOiBmYWN0b3JpYWwobGVuX25hbWVzKS9mYWN0b3JpYWwobGVuX25hbWVzLTMpDQogIG5hbWVzIDwtIGNvbG5hbWVzKGRmKQ0KICBsZW5fbmFtZXMgPSBsZW5ndGgobmFtZXMpDQogIA0KICBpZihpcy5udWxsKGRmcCkpew0KICAgIGRmcCA8LSBsYXBwbHkoMTpsZW5fbmFtZXMsIGZ1bmN0aW9uKGkpew0KICAgICAgdG1wIDwtIGxhcHBseSgxOmxlbl9uYW1lcywgZnVuY3Rpb24oail7DQogICAgICAgIHRtcCA8LSBsYXBwbHkoMTpsZW5fbmFtZXMsIGZ1bmN0aW9uKGspew0KICAgICAgICAgIGlmKGogIT0gaSAmIGsgIT0gaSAmIGsgIT0gaikgYyhuYW1lc1tpXSwgbmFtZXNbal0sIG5hbWVzW2tdKQ0KICAgICAgICB9KQ0KICAgICAgICBkby5jYWxsKHJiaW5kLCB0bXApDQogICAgICB9KQ0KICAgICAgZG8uY2FsbChyYmluZCwgdG1wKQ0KICAgIH0pDQogICAgZGZwIDwtIGRvLmNhbGwocmJpbmQuZGF0YS5mcmFtZSwgZGZwKQ0KICAgIG5hbWVzKGRmcCkgPC0gcGFzdGUoInZhciIsIDE6Mywgc2VwID0gIl8iKQ0KICAgIGRmcFssIF0gPC0gbGFwcGx5KGRmcFssIF0sIGFzLmNoYXJhY3RlcikgICAgDQogIH0gZWxzZSB7DQogICAgZGZwIDwtIGRmcA0KICB9DQogIA0KICANCiAgZm9yIChyb3cgaW4gMTpucm93KGRmcCkpIHsgICAgICAgICAgICAgICAgDQogICAgDQogICAgcmVzdWx0cyA8LSBtZWRtb2Q6Om1lZChkYXRhID0gZGYsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwID0gZGZwW3JvdywgMV0sIG1lZCA9IGRmcFtyb3csIDJdLCBwcmVkID0gZGZwW3JvdywgM10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBjaSA9IFRSVUUsIGxhYmVsID0gVFJVRSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGhzID0gVFJVRSwgcG0gPSBUUlVFLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZXN0UGxvdCA9IEZBTFNFKSAgICAgICAgICAgICANCiAgICANCiAgICBwbWVkIDwtIGFzLmRhdGEuZnJhbWUocmVzdWx0cyRtZWQpWzEsIDhdICAgICAgICAgICAjIHAtdmFsdWUgb2YgSW5kaXJlY3QgRWZmZWN0DQoNCiAgICBpZihwbWVkIDwgMC4wNSAmJiAhaXMubmEocG1lZCkpIHsNCiAgICAgIGNvdW50IDwtIGNvdW50ICsgMQ0KICAgICAgaWYodmVyYm9zZSA9PSBUUlVFKSB7DQogICAgICAgIGNhdCgiTWVkaWF0b3IgVmFyaWFibGU6IiwgZGZwW3JvdywgMl0sICJ8IFByZWRpY3RvcjoiLCBkZnBbcm93LCAzXSwgInwgRGVwZW5kZW50OiIsIGRmcFtyb3csIDFdKQ0KICAgICAgICBwcmludChyZXN1bHRzJG1lZCkNCiAgICAgICAgcHJpbnQocmVzdWx0cyRwYXRocykNCiAgICAgIH0NCiAgICAgIG1lZGlhdGlvbl9tb2RlbF9saXN0W1siTWVkRXMiXV1bW3Bhc3RlKCJtb2RlbCIsIGNvdW50LCBzZXAgPSAiXyIpXV0gPDwtIGFzLmRhdGEuZnJhbWUocmVzdWx0cyRtZWQpICAgIyByZXR1cm4gYXMgbGlzdCBvZiBkYXRhZnJhbWVzDQogICAgICBtZWRpYXRpb25fbW9kZWxfbGlzdFtbIlBhdGhFcyJdXVtbcGFzdGUoIm1vZGVsIiwgY291bnQsIHNlcCA9ICJfIildXSA8PC0gYXMuZGF0YS5mcmFtZShyZXN1bHRzJHBhdGhzKQ0KICAgICAgbWVkaWF0aW9uX21vZGVsX2xpc3RbWyJTeW50YXgiXV1bW3Bhc3RlKCJtb2RlbCIsIGNvdW50LCBzZXAgPSAiXyIpXV0gPDwtIHJlc3VsdHMkbW9kZWxTeW50YXgNCg0KICAgIH0NCiAgfQ0KICBjYXQoIlxuIiwiUmVwb3J0OiAiLCBjb3VudCwgInNpZ25pZmljYW50IG1lZGlhdGlvbnMgb3V0IG9mIiwgcm93LCAidG90YWwgdHJpZXMuIikNCn0NCg0KDQoNCmZpbmRfbW9kIDwtIGZ1bmN0aW9uKGRmLCBkZnAgPSBOVUxMLCBudW1fb25seSA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFKSB7DQogIGNvdW50ID0gMA0KICBtb2RlcmF0aW9uX21vZGVsX2xpc3QgPDwtIGxpc3QoKQ0KDQogIGlmKG51bV9vbmx5ID09IFRSVUUpew0KICBudW1lcmljX2NvbHMgPC0gdW5saXN0KGxhcHBseShkZiwgaXMubnVtZXJpYykpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGdldCBvbmx5IG51bWVyaWMgY29sdW1ucw0KICBkZiA8LSBkZlssIG51bWVyaWNfY29sc10NCiAgfQ0KICANCiAgIyByZXN0cmljdGVkIHBlcm11dGF0aW9ucyBmb3IgTW9kZXJhdGlvbiAtIENoZWNrOiBjaG9vc2UobGVuX25hbWVzLCAzKSozDQogIG5hbWVzIDwtIGNvbG5hbWVzKGRmKQ0KICBsZW5fbmFtZXMgPSBsZW5ndGgobmFtZXMpDQogIA0KICBpZihpcy5udWxsKGRmcCkpew0KICAgIGRmcCA8LSBsYXBwbHkoMTpsZW5fbmFtZXMsIGZ1bmN0aW9uKGkpew0KICAgICAgdG1wIDwtIGxhcHBseSgxOihsZW5fbmFtZXMtMSksIGZ1bmN0aW9uKGopew0KICAgICAgICB0bXAgPC0gbGFwcGx5KChqKzEpOmxlbl9uYW1lcywgZnVuY3Rpb24oayl7DQogICAgICAgICAgaWYoaiAhPSBpICYgayAhPSBpKSBjKG5hbWVzW2ldLCBuYW1lc1tqXSwgbmFtZXNba10pDQogICAgICAgIH0pDQogICAgICAgIGRvLmNhbGwocmJpbmQsIHRtcCkNCiAgICAgIH0pDQogICAgICBkby5jYWxsKHJiaW5kLCB0bXApDQogICAgfSkNCiAgICBkZnAgPC0gZG8uY2FsbChyYmluZC5kYXRhLmZyYW1lLCBkZnApDQogICAgbmFtZXMoZGZwKSA8LSBwYXN0ZSgidmFyIiwgMTozLCBzZXAgPSAiXyIpDQogICAgZGZwWywgXSA8LSBsYXBwbHkoZGZwWywgXSwgYXMuY2hhcmFjdGVyKSAgICANCiAgfSBlbHNlIHsNCiAgICBkZnAgPC0gZGZwDQogIH0NCiAgDQogIGZvciAocm93IGluIDE6bnJvdyhkZnApKSB7ICAgICAgICAgICAgICAgIA0KICAgIA0KICAgIHJlc3VsdHMgPC0gbWVkbW9kOjptb2QoZGF0YSA9IGRmLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbW9kIGRvZXMgY2VudGVyaW5nIGF1dG9tYXRpY2FsbHkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwID0gZGZwW3JvdywgMV0sIG1vZCA9IGRmcFtyb3csIDJdLCBwcmVkID0gZGZwW3JvdywgM10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlc3RNZXRob2QgPSAic3RhbmRhcmQiLCB0ZXN0ID0gVFJVRSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHNpbXBsZVNsb3BlRXN0ID0gRkFMU0UsIHNpbXBsZVNsb3BlUGxvdCA9IEZBTFNFKSAgICAgICAgICAgICAjIHdoZW4gdGVzdGluZyB1c2UgZXN0TWV0aG9kID0gJ2Jvb3RzdHJhcCcsIGJvb3RzdHJhcCA9IDUwMCANCiAgICANCiAgICBwbW9kIDwtIGFzLmRhdGEuZnJhbWUocmVzdWx0cyRtb2QpWzMsNV0NCg0KICAgIGlmKHBtb2QgPCAwLjA1ICYmICFpcy5uYShwbW9kKSkgew0KICAgICAgY291bnQgPC0gY291bnQgKyAxDQogICAgICAgIGlmKHZlcmJvc2UgPT0gVFJVRSkgew0KICAgICAgICBjYXQoIkRlcGVuZGVudCBWYXJpYWJsZToiLCBkZnBbcm93LCAxXSkNCiAgICAgICAgcHJpbnQocmVzdWx0cyRtb2QpIA0KICAgICAgICB9DQogICAgICBtb2RlcmF0aW9uX21vZGVsX2xpc3RbWyJNb2RlbCJdXVtbcGFzdGUoIm1vZGVsIiwgY291bnQsIHNlcCA9ICJfIildXSA8PC0gYXMuZGF0YS5mcmFtZShyZXN1bHRzJG1vZCkgICAjIHJldHVybiBhcyBsaXN0IG9mIGRhdGFmcmFtZXMNCiAgICAgIG1vZGVyYXRpb25fbW9kZWxfbGlzdFtbIlN5bnRheCJdXVtbcGFzdGUoIm1vZGVsIiwgY291bnQsIHNlcCA9ICJfIildXSA8PC0gcmVzdWx0cyRtb2RlbFN5bnRheA0KICAgICAgDQogICAgfQ0KICB9DQogIGNhdCgiXG4iLCJSZXBvcnQ6ICIsIGNvdW50LCAic2lnbmlmaWNhbnQgbW9kZXJhdGlvbnMgb3V0IG9mIiwgcm93LCAidG90YWwgdHJpZXMuIikNCn0NCg0KDQpgYGANCg0KDQpgYGB7ciBkZWZfZnVuX0xDU21lZCwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIyMgTENTIEFOQ09WQSBtZWRpYXRpb24gZnVuY3Rpb24gKGFkYXB0ZWQgZm9yIGxhdmFhbiBmcm9tIGRvaTogMTAuMTA4MC8xMDcwNTUxMS4yMDE2LjEyNzQ2NTcpDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KbGlicmFyeShsYXZhYW4pDQpsaWJyYXJ5KHNlbVBsb3QpDQoNCmxjc19hbmNvdmFfbWVkIDwtIGZ1bmN0aW9uKGRmLCB4LCB5MSwgeTIsIG0xLCBtMil7DQogIA0KICBhcmd1bWVudHMgPC0gYXMubGlzdChtYXRjaC5jYWxsKCkpDQogIHggPSBldmFsKGFyZ3VtZW50cyR4LCBkZikNCiAgeTEgPSBldmFsKGFyZ3VtZW50cyR5MSwgZGYpDQogIHkyID0gZXZhbChhcmd1bWVudHMkeTIsIGRmKQ0KICBtMSA9IGV2YWwoYXJndW1lbnRzJG0xLCBkZikNCiAgbTIgPSBldmFsKGFyZ3VtZW50cyRtMiwgZGYpICANCiAgDQogIGRmX21vZCA8LSBkYXRhLmZyYW1lKHgsIHkxLCB5MiwgbTEsIG0yKSAgICAgIyB1c2UgdGhpcyBkZiBjcmVhdGluZyBwYXJ0IGxpa2UgdGhpczogbGNzX2FuY292YV9tZWQobXRjYXJzLCBtcGcsIGN5bCwgZGlzcCwgaHAsIGRyYXQpDQoNCiAgbW9kX3N5bnRheCA8LSANCiAgJw0KICAjIERlZmluaW5nIGNoYW5nZSBpbiBNIGFzIGEgZnVuY3Rpb24gb2YgTTEgYW5kIE0yDQogIGRlbHRhbSA9fiAxKm0yDQogIGRlbHRhbSB+fiBkZWx0YW0NCiAgZGVsdGFtIH4gMQ0KICBtMiB+IDEqbTENCiAgbTIgfn4gMCptMQ0KICBtMiB+fiAwKm0yDQogIG0yIH4gMCoxDQogIG0xIH4gMQ0KICAjIERlZmluaW5nIHRoZSBjaGFuZ2UgaW4gWSBhcyBhIGZ1bmN0aW9uIG9mIFkxIGFuZCBZMg0KICBkZWx0YXkgPX4gMSp5Mg0KICBkZWx0YXkgfn4gZGVsdGF5DQogIGRlbHRheSB+IDENCiAgeTIgfiAxKnkxDQogIHkyIH5+IDAqeTENCiAgeTIgfn4gMCp5Mg0KICB5MiB+IDAqMQ0KICB5MSB+IDENCiAgIyBFc3RpbWF0aW5nIHRoZSBQcmV0ZXN0IGNvcnJlbGF0aW9uIGJldHdlZW4gTTEgYW5kIFkxIGFuZCBWYXJpYW5jZSBvZiBYDQogIG0xIH5+IHkxDQogICMgRXN0aW1hdGVkIGNvdmFyaWFuY2UgYmV0d2VlbiBNMSBhbmQgWCBhbmQgWTEgYW5kIFggYmVjYXVzZSB0aGVzZSBjb3ZhcmlhbmNlcyBtYXkgbm90IGJlIGVxdWFsIHRvIHplcm8gZXNwZWNpYWxseSANCiAgIyBpZiBYIGlzIG5vdCBhIHJhbmRvbWl6ZWQgZXhwZXJpbWVudCB3aXRob3V0IHRoZXNlIHRoZSBtb2RlbCBoYXMgMiBkZWdyZWVzIG9mIGZyZWVkb20gKGNvdmFyaWFuY2VzIGFyZSBvbmx5IGNvbnN0cmFpbmVkIHRvIHplcm8pIA0KICAjIGJ1dCBBTkNPVkEgbW9kZWwgc2hvdWxkIHN0YXJ0IG91dCBhcyBzYXR1cmF0ZWQgYW5kIGhhdmUgMCBkZWdyZWVzIG9mIGZyZWVkb20gDQogIG0xIH5+IHggIyB0aGVzZSBjb3ZhcmlhbmNlcyBtYXkgbm90IGJlIGVxdWFsIHRvIHplcm8gZXNwZWNpYWxseSBpZiBYIGlzIG5vdCBhIHJhbmRvbWl6ZWQgZXhwZXJpbWVudA0KICB4IH5+IHkxICMgdGhlc2UgY292YXJpYW5jZXMgbWF5IG5vdCBiZSBlcXVhbCB0byB6ZXJvIGVzcGVjaWFsbHkgaWYgWCBpcyBub3QgYSByYW5kb21pemVkIGV4cGVyaW1lbnQNCiAgIyBSZWdyZXNzaW9uIG9mIGNoYW5nZSBpbiBNIG9uIFggYW5kIHByZXRlc3QgbWVhc3VyZXMNCiAgZGVsdGFtIH4gYW0yeCp4ICsgc20xKm0xICsgeTENCiAgIyBSZWdyZXNzaW9uIG9mIGNoYW5nZSBpbiBZIG9uIFgsIGNoYW5nZSBpbiBNLCBhbmQgcHJldGVzdCBtZWFzdXJlcw0KICBkZWx0YXkgfiB4ICsgYnkybTIqZGVsdGFtICsgYiptMSArIHN5MSp5MQ0KICANCiAgIyBNYWtpbmcgY29uc3RyYWludHMgdG8gbWF0Y2ggZXN0aW1hdGVzIHRvIEFOQ09WQQ0KICAjIEVzdGltYXRlIG9mIGVmZmVjdCBvZiBNMSBvbiBNMiBpbiBBTkNPVkENCiAgc20gOj0gc20xKzEgDQogICMgRXN0aW1hdGUgb2YgZWZmZWN0IG9mIFkxIG9uIFkyIGluIEFOQ09WQQ0KICBzeSA6PSBzeTErMSANCiAgIyBFc3RpbWF0ZSBvZiBlZmZlY3Qgb2YgTTEgb24gWTIgaW4gQU5DT1ZBDQogIGJ5Mm0xIDo9IGItYnkybTIgDQogICMgRXN0aW1hdGUgb2YgbWVkaWF0ZWQgZWZmZWN0DQogIG1lZCA6PSBhbTJ4KmJ5Mm0yIA0KICAnICANCiAgDQogIG1vZCA8LSBsYXZhYW46OnNlbShtb2RlbCA9IG1vZF9zeW50YXgsIGRhdGEgPSBkZl9tb2QsIHRlc3QgPSAiYm9vdHN0cmFwIikgIA0KfQ0KDQoNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIFVzZSAtIGRvbnQgcnVuDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KIyBtb2QgPC0gbGNzX2FuY292YV9tZWQoZGYgPSBkZjIsIHggPSBDb25kLCB5MSA9IE91dDEsIHkyID0gT3V0MiwgbTEgPSBNZWQxLCBtMiA9IE1lZDIpDQojIA0KIyBzdW1tYXJ5KG1vZCwgc3RhbmRhcmRpemVkID0gVFJVRSkNCiMgc2VtUGxvdDo6c2VtUGF0aHMobW9kLCBsYXlvdXQgPSAic3ByaW5nIiwgIG5DaGFyTm9kZXMgPSAwLCBuQ2hhckVkZ2VzID0gMCwgd2hhdCA9ICJwYXRoIiwgd2hhdExhYmVscyA9ICJwYXRoIiwgZWRnZS5sYWJlbC5jZXggPSAwLjgpIA0KDQpgYGANCg0KDQojIERvd25sb2FkYWJsZSBUYWJsZQ0KDQpgYGB7ciBkdF90YWJsZX0NCkRhdGEgJT4lIA0KICBzZWxlY3QoLSJOdW1lIFByZW51bWUiKSAlPiUNCiAgICBEVDo6ZGF0YXRhYmxlKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGV4Y2VsIGRvd25sb2FkYWJsZSAgRFQgdGFibGUNCiAgICAgIGV4dGVuc2lvbnMgPSAnQnV0dG9ucycsDQogICAgICBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMTAsDQogICAgICAgICAgICAgICAgICAgICBzY3JvbGxYPSc1MDBweCcsIA0KICAgICAgICAgICAgICAgICAgICAgZG9tID0gJ0JmcnRpcCcsIA0KICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2V4Y2VsJywgImNzdiIpKSkNCmBgYA0KDQoNCiMgQW5hbHlzZXMNCg0KIyMgTWVsdCBEYXRhDQoNCmBgYHtyIG1lbHRfZGF0YX0NCkRhdGFfbWVkIDwtIERhdGEgJT4lDQogIHNlbGVjdCgtYygxOjQsNiw3KSwgDQogICAgICAgICAtYygiREdfcHJlUG96MSIsICJER19wcmVQb3oyIiwgIkRHX3ByZVBvejMiLCAiREdfcG9zdFBvejEiLCAiREdfcG9zdFBvejIiLCAiREdfcG9zdFBvejMiLCAgDQogICAgICAgICAgICJER19wcmVOZWcxIiwgIkRHX3ByZU5lZzIiLCAiREdfcHJlTmVnMyIgLCAiREdfcG9zdE5lZzEiLCAiREdfcG9zdE5lZzIiLCAiREdfcG9zdE5lZzMiKSkNCg0KIyMgRGF0YSBub3QgbWVsdGVkIHRvIGxvbmcNCiMgRGF0YV9tZWQgJT4lDQojICAgZmluZF9tZWQoKSAgICAgICAjIG5vdCBydW4gaGVyZSB0byBrZWVwIHJlcG9ydCBjbGVhbg0KDQojIyBEYXRhIG1lbHRlZCB0byBsb25nIChDb25kID0gUG96L05lZykNCiMgRGF0YV9tZWRfbWVsdCA8LSANCiMgICBEYXRhX21lZCAlPiUNCiMgICAgIGRwbHlyOjpyZW5hbWVfYWxsKGxpc3QofnN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbCguLCAiUHJlfF9wcmV8X1ByZSIsICJfcHJlIikpKSAlPiUgICAgICAgICAjIGNvbnNpc3RlbnQgQ29uZGl0aW9uIGFuZCBUaW1lDQojICAgICBkcGx5cjo6cmVuYW1lX2FsbChsaXN0KH5zdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoLiwgIlBvc3R8X3Bvc3R8X1Bvc3QiLCAiX3Bvc3QiKSkpICU+JQ0KIyAgICAgZHBseXI6OnJlbmFtZV9hbGwobGlzdCh+c3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKC4sICJQb3p8cG96fF9Qb3p8X3BveiIsICJfcG96IikpKSAlPiUNCiMgICAgIGRwbHlyOjpyZW5hbWVfYWxsKGxpc3QofnN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbCguLCAiTmVnfG5lZ3xfTmVnfF9uZWciLCAiX25lZyIpKSkgJT4lDQojICAgICBkcGx5cjo6cmVuYW1lX2FsbChsaXN0KH5zdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoLiwgIl9uZWdfcHJlIiwgIl9wcmVfbmVnIikpKSAlPiUgICAgICAgICAgIyBjb25zaXN0ZW50IG9yZGVyaW5nIGluIG5hbWVzDQojICAgICBkcGx5cjo6cmVuYW1lX2FsbChsaXN0KH5zdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoLiwgIl9uZWdfcG9zdCIsICJfcG9zdF9uZWciKSkpICU+JQ0KIyAgICAgZHBseXI6OnJlbmFtZV9hbGwobGlzdCh+c3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKC4sICJfcG96X3ByZSIsICJfcHJlX3BveiIpKSkgJT4lDQojICAgICBkcGx5cjo6cmVuYW1lX2FsbChsaXN0KH5zdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoLiwgIl9wb3pfcG9zdCIsICJfcG9zdF9wb3oiKSkpICU+JQ0KIyAgICAgZHBseXI6OnJlbmFtZV9hbGwobGlzdCh+c3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKC4sICJUb3QiLCAiIikpKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICMgZGV0ZWxlIFRvdCAiREdfcHJlX25lZ1RvdCIsICJUcnVzdFRvdF9wb3N0X3BveiINCiMgICAgIGdhdGhlcihWYXIsIFZhbCwgLWMoMTozOCkpICU+JQ0KIyAgICAgc2VwYXJhdGUoVmFyLCBpbnRvID0gYygiVmFyIiwgIlRpbWUiLCAiQ29uZGl0aW9uIikpICU+JQ0KIyAgICAgbXV0YXRlKFRpbWUgPSBmYWN0b3IoVGltZSwgbGV2ZWxzID0gYygicHJlIiwgInBvc3QiKSkpICU+JQ0KIyAgICAgbXV0YXRlKENvbmRpdGlvbiA9IGZhY3RvcihDb25kaXRpb24sIGxldmVscyA9IGMoInBveiIsICJuZWciKSkpICU+JQ0KIyAgICAgc3ByZWFkKFZhciwgVmFsKSANCg0KRGF0YV9tZWRfbWVsdCA8LSANCiAgRGF0YV9tZWQgJT4lDQogICAgZHBseXI6OnJlbmFtZV9hbGwobGlzdCh+c3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKC4sICJQcmV8X3ByZXxfUHJlIiwgIl9wcmUiKSkpICU+JSAgICAgICAgICMgY29uc2lzdGVudCBDb25kaXRpb24gYW5kIFRpbWUNCiAgICBkcGx5cjo6cmVuYW1lX2FsbChsaXN0KH5zdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoLiwgIlBvc3R8X3Bvc3R8X1Bvc3QiLCAiX3Bvc3QiKSkpICU+JQ0KICAgIGRwbHlyOjpyZW5hbWVfYWxsKGxpc3QofnN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbCguLCAiUG96fHBvenxfUG96fF9wb3oiLCAiX3BveiIpKSkgJT4lDQogICAgZHBseXI6OnJlbmFtZV9hbGwobGlzdCh+c3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKC4sICJOZWd8bmVnfF9OZWd8X25lZyIsICJfbmVnIikpKSAlPiUNCiAgICBkcGx5cjo6cmVuYW1lX2FsbChsaXN0KH5zdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoLiwgIl9uZWdfcHJlIiwgIl9wcmVfbmVnIikpKSAlPiUgICAgICAgICAgIyBjb25zaXN0ZW50IG9yZGVyaW5nIGluIG5hbWVzDQogICAgZHBseXI6OnJlbmFtZV9hbGwobGlzdCh+c3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKC4sICJfbmVnX3Bvc3QiLCAiX3Bvc3RfbmVnIikpKSAlPiUNCiAgICBkcGx5cjo6cmVuYW1lX2FsbChsaXN0KH5zdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoLiwgIl9wb3pfcHJlIiwgIl9wcmVfcG96IikpKSAlPiUNCiAgICBkcGx5cjo6cmVuYW1lX2FsbChsaXN0KH5zdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoLiwgIl9wb3pfcG9zdCIsICJfcG9zdF9wb3oiKSkpICU+JQ0KICAgIGRwbHlyOjpyZW5hbWVfYWxsKGxpc3QofnN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbCguLCAiVG90IiwgIiIpKSkgJT4lICAgICAgICAgICAgICAgICAgICAgICAjIGRldGVsZSBUb3QgIkRHX3ByZV9uZWdUb3QiLCAiVHJ1c3RUb3RfcG9zdF9wb3oiDQogICAgZ2F0aGVyKFZhciwgVmFsLCAtYygxOjM4KSkgJT4lDQogICAgdGlkeXI6OnNlcGFyYXRlKFZhciwgaW50byA9IGMoIlZhciIsICJUaW1lIiwgIkNvbmRpdGlvbiIpKSAlPiUNCiAgICB0aWR5cjo6dW5pdGUoIlZhciIsIGMoIlZhciIsICJUaW1lIikpICU+JQ0KICAgIG11dGF0ZShDb25kaXRpb24gPSBmYWN0b3IoQ29uZGl0aW9uLCBsZXZlbHMgPSBjKCJwb3oiLCAibmVnIikpKSAlPiUNCiAgICBtdXRhdGUoQ29uZGl0aW9uID0gZHBseXI6OnJlY29kZShDb25kaXRpb24sICJwb3oiID0gMSwgIm5lZyIgPSAyKSkgJT4lIA0KICAgIHNwcmVhZChWYXIsIFZhbCkgDQoNCmBgYA0KDQoNCiMjIFNlYXJjaCBNZWRpYXRpb25zIGFuZCBNb2RlcmF0aW9ucw0KDQpgYGB7ciBmaW5kX21lZG1vZCwgcmVzdWx0cz0naGlkZSd9DQpkZnAgPC0gZGF0YS5mcmFtZSgNCiAgdmFyMSA9IGNvbG5hbWVzKERhdGFfbWVkX21lbHQpW2dyZXAoIl9wb3N0IiwgY29sbmFtZXMoRGF0YV9tZWRfbWVsdCkpXSwNCiAgdmFyMiA9IHJlcCgiQ29uZGl0aW9uIiwgMTMpLA0KICB2YXIzID0gY29sbmFtZXMoRGF0YV9tZWRfbWVsdClbZ3JlcCgiX3ByZSIsIGNvbG5hbWVzKERhdGFfbWVkX21lbHQpKV0sDQogIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQ0KKQ0KDQpmaW5kX21lZChkZiA9IERhdGFfbWVkX21lbHQsIGRmcCA9IGRmcCwgbnVtX29ubHkgPSBGQUxTRSkgICAgICAgICAgICAgICAgICMgbm90aGluZw0KZmluZF9tb2QoZGYgPSBEYXRhX21lZF9tZWx0LCBkZnAgPSBkZnAsIG51bV9vbmx5ID0gRkFMU0UpICAgICAgICAgICAgICAgICAjIERHX3ByZTpDb25kaXRpb24NCg0KDQojIG1lZG1vZDo6bWVkKGRhdGEgPSBEYXRhX21lZF9tZWx0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQojICAgICAgICAgICAgZGVwID0gIk94X3Bvc3QiLCBtZWQgPSAiQ29uZGl0aW9uIiwgcHJlZCA9ICJPeF9wcmUiLCANCiMgICAgICAgICAgICBjaSA9IFRSVUUsIGxhYmVsID0gVFJVRSwgDQojICAgICAgICAgICAgcGF0aHMgPSBUUlVFLCBwbSA9IFRSVUUsIA0KIyAgICAgICAgICAgIGVzdFBsb3QgPSBGQUxTRSkNCiMgDQojIG1lZG1vZDo6bW9kKGRhdGEgPSBEYXRhX21lZF9tZWx0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbW9kIGRvZXMgY2VudGVyaW5nIGF1dG9tYXRpY2FsbHkNCiMgICAgICAgICAgICAgZGVwID0gIk94X3Bvc3QiLCBtb2QgPSAiQ29uZGl0aW9uIiwgcHJlZCA9ICJPeF9wcmUiLCAgDQojICAgICAgICAgICAgIGVzdE1ldGhvZCA9ICJzdGFuZGFyZCIsIHRlc3QgPSBUUlVFLCANCiMgICAgICAgICAgICAgc2ltcGxlU2xvcGVFc3QgPSBGQUxTRSwgc2ltcGxlU2xvcGVQbG90ID0gRkFMU0UpDQoNCmBgYA0KDQoNCmBgYHtyIGZpbmRfbWVkbW9kX291dHB1dH0NCiMgbWVkaWF0aW9uX21vZGVsX2xpc3QkTW9kZWwgICAjIG5vIG1vZGVscyB0byBzaG93DQptb2RlcmF0aW9uX21vZGVsX2xpc3QkTW9kZWwgJT4lIA0KICBrbml0cjo6a2FibGUoZGlnaXRzID0gMikNCmBgYA0KDQoNCiMjIExDUyBBTkNPVkEgbG9uZ2l0dWRpbmFsIG1lZGlhdGlvbg0KDQpgYGB7ciBmaW5kX0xDU21lZH0NCkRhdGFfbWVkX21lbHRfdHJhbnNmb3JtIDwtIERhdGFfbWVkX21lbHQgICAgIyBzb21lIG9ic2VydmVkIHZhcmlhbmNlcyBhcmUgKGF0IGxlYXN0KSBhIGZhY3RvciAxMDAwIHRpbWVzIGxhcmdlciB0aGFuIG90aGVycw0KRGF0YV9tZWRfbWVsdF90cmFuc2Zvcm0kREdfcHJlIDwtIERhdGFfbWVkX21lbHRfdHJhbnNmb3JtJERHX3ByZSAvIDEwMCAgDQpEYXRhX21lZF9tZWx0X3RyYW5zZm9ybSRER19wb3N0IDwtIERhdGFfbWVkX21lbHRfdHJhbnNmb3JtJERHX3Bvc3QgLyAxMDANCg0KbW9kIDwtIGxjc19hbmNvdmFfbWVkKGRmID0gRGF0YV9tZWRfbWVsdF90cmFuc2Zvcm0sIHggPSBDb25kaXRpb24sIHkxID0gREdfcHJlLCB5MiA9IERHX3Bvc3QsIG0xID0gT3hfcHJlLCBtMiA9IE94X3Bvc3QpDQpzdW1tYXJ5KG1vZCwgc3RhbmRhcmRpemVkID0gVFJVRSkgICAgIyBub3BlDQpzZW1QbG90OjpzZW1QYXRocyhtb2QsIGxheW91dCA9ICJzcHJpbmciLCAgbkNoYXJOb2RlcyA9IDAsIG5DaGFyRWRnZXMgPSAwLCB3aGF0ID0gInBhdGgiLCB3aGF0TGFiZWxzID0gInBhdGgiLCBlZGdlLmxhYmVsLmNleCA9IDAuOCkgDQoNCg0KIyBtb2QgPC0gbGNzX2FuY292YV9tZWQoZGYgPSBEYXRhX21lZF9tZWx0LCB4ID0gQ29uZGl0aW9uLCB5MSA9IFZhc1NfcHJlLCB5MiA9IFZhc1NfcG9zdCwgbTEgPSBPeF9wcmUsIG0yID0gT3hfcG9zdCkNCiMgc3VtbWFyeShtb2QsIHN0YW5kYXJkaXplZCA9IFRSVUUpICAgICMgbm9wZQ0KIyANCiMgbW9kIDwtIGxjc19hbmNvdmFfbWVkKGRmID0gRGF0YV9tZWRfbWVsdCwgeCA9IENvbmRpdGlvbiwgeTEgPSBWYXNCX3ByZSwgeTIgPSBWYXNCX3Bvc3QsIG0xID0gT3hfcHJlLCBtMiA9IE94X3Bvc3QpDQojIHN1bW1hcnkobW9kLCBzdGFuZGFyZGl6ZWQgPSBUUlVFKSAgICAjIG5vcGUNCiMgDQojIG1vZCA8LSBsY3NfYW5jb3ZhX21lZChkZiA9IERhdGFfbWVkX21lbHQsIHggPSBDb25kaXRpb24sIHkxID0gSU9TX3ByZSwgeTIgPSBJT1NfcG9zdCwgbTEgPSBPeF9wcmUsIG0yID0gT3hfcG9zdCkNCiMgc3VtbWFyeShtb2QsIHN0YW5kYXJkaXplZCA9IFRSVUUpICAgICMgbm9wZQ0KIyANCiMgbW9kIDwtIGxjc19hbmNvdmFfbWVkKGRmID0gRGF0YV9tZWRfbWVsdCwgeCA9IENvbmRpdGlvbiwgeTEgPSBUcnVzdF9wcmUsIHkyID0gVHJ1c3RfcG9zdCwgbTEgPSBPeF9wcmUsIG0yID0gT3hfcG9zdCkNCiMgc3VtbWFyeShtb2QsIHN0YW5kYXJkaXplZCA9IFRSVUUpICAgICMgbm9wZQ0KIyANCiMgDQojIA0KIyBtb2QgPC0gbGNzX2FuY292YV9tZWQoZGYgPSBEYXRhX21lZF9tZWx0LCB4ID0gQ29uZGl0aW9uLCB5MSA9IE94X3ByZSwgeTIgPSBPeF9wb3N0LCBtMSA9IElPU19wcmUsIG0yID0gSU9TX3Bvc3QpDQojIHN1bW1hcnkobW9kLCBzdGFuZGFyZGl6ZWQgPSBUUlVFKSAgICAjIG5vcGUNCiMgDQojIG1vZCA8LSBsY3NfYW5jb3ZhX21lZChkZiA9IERhdGFfbWVkX21lbHQsIHggPSBDb25kaXRpb24sIHkxID0gT3hfcHJlLCB5MiA9IE94X3Bvc3QsIG0xID0gVmFzU19wcmUsIG0yID0gVmFzU19wb3N0KQ0KIyBzdW1tYXJ5KG1vZCwgc3RhbmRhcmRpemVkID0gVFJVRSkgICAgIyBub3BlDQojIA0KIyBtb2QgPC0gbGNzX2FuY292YV9tZWQoZGYgPSBEYXRhX21lZF9tZWx0LCB4ID0gQ29uZGl0aW9uLCB5MSA9IE94X3ByZSwgeTIgPSBPeF9wb3N0LCBtMSA9IFZhc0JfcHJlLCBtMiA9IFZhc0JfcG9zdCkNCiMgc3VtbWFyeShtb2QsIHN0YW5kYXJkaXplZCA9IFRSVUUpICAgICMgbm9wZQ0KIyANCiMgDQojIA0KIyBtb2QgPC0gbGNzX2FuY292YV9tZWQoZGYgPSBEYXRhX21lZF9tZWx0LCB4ID0gQ29uZGl0aW9uLCB5MSA9IENvcnRfcHJlLCB5MiA9IENvcnRfcG9zdCwgbTEgPSBJT1NfcHJlLCBtMiA9IElPU19wb3N0KQ0KIyBzdW1tYXJ5KG1vZCwgc3RhbmRhcmRpemVkID0gVFJVRSkgICAgIyBub3BlDQojIA0KIyBtb2QgPC0gbGNzX2FuY292YV9tZWQoZGYgPSBEYXRhX21lZF9tZWx0LCB4ID0gQ29uZGl0aW9uLCB5MSA9IENvcnRfcHJlLCB5MiA9IENvcnRfcG9zdCwgbTEgPSBWYXNTX3ByZSwgbTIgPSBWYXNTX3Bvc3QpDQojIHN1bW1hcnkobW9kLCBzdGFuZGFyZGl6ZWQgPSBUUlVFKSAgICAjIG5vcGUNCiMgDQojIG1vZCA8LSBsY3NfYW5jb3ZhX21lZChkZiA9IERhdGFfbWVkX21lbHQsIHggPSBDb25kaXRpb24sIHkxID0gQ29ydF9wcmUsIHkyID0gQ29ydF9wb3N0LCBtMSA9IFZhc0JfcHJlLCBtMiA9IFZhc0JfcG9zdCkNCiMgc3VtbWFyeShtb2QsIHN0YW5kYXJkaXplZCA9IFRSVUUpICAgICMgbm9wZQ0KYGBgDQoNCg0KDQoNCg0KPGJyPg0KDQoNCg0KPCEtLSBTZXNzaW9uIEluZm8gYW5kIExpY2Vuc2UgLS0+DQoNCjxicj4NCg0KIyBTZXNzaW9uIEluZm8NCmBgYHtyIHNlc3Npb25faW5mbywgZWNobyA9IEZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9DQpzZXNzaW9uSW5mbygpICAgIA0KYGBgDQoNCjwhLS0gRm9vdGVyIC0tPg0KJm5ic3A7DQo8aHIgLz4NCjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij5BIHdvcmsgYnkgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL0NsYXVkaXVQYXBhc3RlcmkvIj5DbGF1ZGl1IFBhcGFzdGVyaTwvYT48L3A+DQo8cCBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyI+PHNwYW4gc3R5bGU9ImNvbG9yOiAjODA4MDgwOyI+PGVtPmNsYXVkaXUucGFwYXN0ZXJpQGdtYWlsLmNvbTwvZW0+PC9zcGFuPjwvcD4NCiZuYnNwOw0K